package com.example.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.HttpStatusEnum;
import com.example.entity.ChartStrData;
import com.example.entity.ChartTimeData;
import com.example.entity.ResponseData;
import com.example.entity.VoDiagnosisDrList;
import com.example.mapper.AppointmentMapper;
import com.example.mapper.PrescriptionMapper;
import com.example.mapper.UserMapper;
import com.example.pojo.Appointment;
import com.example.pojo.Diagnosis;
import com.example.mapper.DiagnosisMapper;
import com.example.pojo.Prescription;
import com.example.pojo.User;
import com.hankcs.hanlp.HanLP;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * 诊断信息表(Diagnosis)表服务实现类
 *
 * @email: pengyujun53@163.com
 * @author: peng_YuJun
 * @date: 2024/01/17
 * @time: 23:13
 */
@Service
public class DiagnosisService {
    /**
     * mapper对象
     */
    @Resource
    private AppointmentMapper appointmentMapper;
    @Resource
    private DiagnosisMapper diagnosisMapper;
    @Resource
    private PrescriptionMapper prescriptionMapper;
    @Resource
    private UserMapper userMapper;

    /**
     * 分页查询
     *
     * @param currentPage
     * @param pageSize
     * @param diagnosis   筛选条件
     * @return
     */
    public ResponseData getByPage(Integer currentPage, Integer pageSize, Diagnosis diagnosis) {
        QueryWrapper<Diagnosis> qw = new QueryWrapper<>();
        //TODO: getByPage diagnosis qw查询条件待构建
        IPage ipage = new Page(currentPage, pageSize);
        diagnosisMapper.selectPage(ipage, qw);
        //若当前页码大于总页面数
        if (currentPage > ipage.getPages()) {
            ipage = new Page(ipage.getPages(), pageSize);
            diagnosisMapper.selectPage(ipage, qw);
        }
        if (ipage.getTotal() <= 0) {
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), ipage);
    }

    /**
     * 根据ID查询信息
     *
     * @param id 主键
     * @return 单条数据
     */
    public ResponseData findById(Long id) {
        Diagnosis diagnosis = diagnosisMapper.selectById(id);
        if (diagnosis == null || diagnosis.getId() == null) {
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        //返回结果
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), diagnosis);
    }

    /**
     * 新增数据
     *
     * @param diagnosis 实体
     * @return 新增结果
     */
    public ResponseData add(Diagnosis diagnosis) {
        //插入
        if (diagnosisMapper.insert(diagnosis) > 0) {
            return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage());
        }
        return new ResponseData(HttpStatusEnum.ERROR.getCode(), "新增失败，请稍后再试");
    }

    /**
     * 更新数据
     *
     * @param diagnosis 实体
     * @return 更新结果
     */
    public ResponseData update(Diagnosis diagnosis) {
        //更新
        if (diagnosisMapper.updateById(diagnosis) > 0) {
            return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage());
        }
        return new ResponseData(HttpStatusEnum.ERROR.getCode(), "修改失败，请稍后再试");
    }

    /**
     * 删除数据
     *
     * @param id 主键
     * @return
     */
    public ResponseData delete(Long id) {
        if (diagnosisMapper.deleteById(id) > 0) {
            //返回成功响应
            return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage());
        }
        return new ResponseData(HttpStatusEnum.ERROR.getCode(), "删除失败，请稍后再试");
    }

    /**
     * 批量删除
     *
     * @param idList
     * @return
     */
    public ResponseData deleteBatch(List<Long> idList) {
        if (diagnosisMapper.deleteBatchIds(idList) > 0) {
            //返回成功响应
            return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage());
        }
        return new ResponseData(HttpStatusEnum.ERROR.getCode(), "删除失败，请稍后再试");
    }

    /**
     * 更新评论内容
     *
     * @param id
     * @param evaluation
     * @return
     */
    public ResponseData updateEvaluation(Long id, String evaluation, Integer stars) {
        UpdateWrapper<Diagnosis> uw = new UpdateWrapper<>();
        uw.eq("id", id);
        uw.set("evaluation", evaluation);
        uw.set("stars", stars);
        // 开始取消
        if (diagnosisMapper.update(null, uw) > 0) {
            //返回成功响应
            return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage());
        }
        return new ResponseData(HttpStatusEnum.ERROR.getCode(), "评论失败，请稍后再试");
    }

    /**
     * 新增诊断和药单信息
     * @param symptoms
     * @param diagnosisMsg
     * @param medicines
     * @param dosage
     * @param useway
     * @param price
     * @param aptId
     * @param sign
     * @return
     */
    public ResponseData makeDiagnosis(String symptoms, String diagnosisMsg, String medicines, String dosage, String useway,
                                      Double price, Long aptId, String sign) {
        Appointment appointment = appointmentMapper.selectById(aptId);
        if (appointment == null || appointment.getId() == null){
            return new ResponseData(HttpStatusEnum.ERROR.getCode(), "该预约信息不存在");
        }
        // 病单信息
        Diagnosis diagnosis = new Diagnosis();
        diagnosis.setApmtId(aptId);
        diagnosis.setPtId(appointment.getPtId());
        diagnosis.setDrId(appointment.getDrId());
        diagnosis.setSymptoms(symptoms);
        diagnosis.setDiagnosis(diagnosisMsg);
        diagnosis.setStatus(1);
        diagnosis.setSignature(sign);
        // 开始插入
        diagnosisMapper.insert(diagnosis);
        // 药单信息
        if (StringUtils.hasText(medicines)){
            Prescription prescription = new Prescription();
            prescription.setApmtId(aptId);
            prescription.setPtId(appointment.getPtId());
            prescription.setDrId(appointment.getDrId());
            prescription.setMedicines(medicines);
            prescription.setDosage(dosage);
            prescription.setUseway(useway);
            prescription.setAmount(price);
            prescription.setStatus(1);
            prescription.setSignature(sign);
            // 开始插入
            prescriptionMapper.insert(prescription);
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), "上传成功！");
    }

    /**
     * 新增即时诊断和药单信息
     * @param symptoms
     * @param diagnosisMsg
     * @param medicines
     * @param dosage
     * @param useway
     * @param price
     * @param drId
     * @param stuCode
     * @param sign
     * @return
     */
    public ResponseData makeGoDiagnosis(String symptoms, String diagnosisMsg, String medicines, String dosage,
                                        String useway, Double price, Long drId, String stuCode, String sign) {
        // 查找学生
        LambdaQueryWrapper<User> userLqw = new LambdaQueryWrapper<>();
        userLqw.eq(User::getCode, stuCode);
        User patient = userMapper.selectOne(userLqw);
        if (patient == null || patient.getId() == null){
            return new ResponseData(HttpStatusEnum.ERROR.getCode(), "学工号不存在");
        }
        // 会话单信息
        Appointment appointment = new Appointment();
        appointment.setPtId(patient.getId());
        appointment.setDrId(drId);
        appointment.setTime(new Date());
        appointment.setStage(0);
        appointment.setStatus(1);
        appointmentMapper.insert(appointment);
        // 病单信息
        Diagnosis diagnosis = new Diagnosis();
        diagnosis.setApmtId(appointment.getId());
        diagnosis.setPtId(appointment.getPtId());
        diagnosis.setDrId(appointment.getDrId());
        diagnosis.setSymptoms(symptoms);
        diagnosis.setDiagnosis(diagnosisMsg);
        diagnosis.setStatus(1);
        diagnosis.setSignature(sign);
        // 开始插入
        diagnosisMapper.insert(diagnosis);
        if (StringUtils.hasText(medicines)){
            // 药单信息
            Prescription prescription = new Prescription();
            prescription.setApmtId(appointment.getId());
            prescription.setPtId(appointment.getPtId());
            prescription.setDrId(appointment.getDrId());
            prescription.setMedicines(medicines);
            prescription.setDosage(dosage);
            prescription.setUseway(useway);
            prescription.setAmount(price);
            prescription.setStatus(1);
            prescription.setSignature(sign);
            // 开始插入
            prescriptionMapper.insert(prescription);
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), "上传成功！");
    }

    /**
     * 根据病患id查询记录
     * @param ptId
     * @return
     */
    public ResponseData findByPtId(Long ptId) {
        List<VoDiagnosisDrList> voDiagnosisList = diagnosisMapper.selectListVoByPtId(ptId);
        if (voDiagnosisList == null || voDiagnosisList.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), voDiagnosisList);
    }

    /**
     * 根据医生id查询记录
     * @param drId
     * @return
     */
    public ResponseData findByDrId(Long drId) {
        List<VoDiagnosisDrList> voDiagnosisList = diagnosisMapper.selectListVoByDrId(drId);
        if (voDiagnosisList == null || voDiagnosisList.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), voDiagnosisList);
    }

    /**
     * 计算就诊频率
     * @return
     */
    public ResponseData countDiagnosisFreq() {
        List<ChartTimeData> chartTimeData = diagnosisMapper.countDiagnosisFreq();
        if (chartTimeData == null || chartTimeData.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), chartTimeData);
    }

    /**
     * 计算确诊频率
     * @return
     */
    public ResponseData countDiseaseFreq() {
        List<ChartStrData> chartStrData = diagnosisMapper.countDiseaseFreq();
        if (chartStrData == null || chartStrData.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), chartStrData);
    }

    /**
     * 统计病历数
     * @return
     */
    public ResponseData countAll() {
        Long all = diagnosisMapper.selectCount(null);
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), all);
    }

    /**
     * 统计不同时间段就诊数
     * @return
     */
    public ResponseData countPeriod() {
        List<ChartStrData> chartStrData = diagnosisMapper.countPeriod();
        if (chartStrData == null || chartStrData.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), chartStrData);
    }

    /**
     * 统计不同科室就诊数
     * @return
     */
    public ResponseData countEntVisits() {
        List<ChartStrData> chartStrData = diagnosisMapper.countEntVisits();
        if (chartStrData == null || chartStrData.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), chartStrData);
    }

    /**
     * 统计满意度
     * @return
     */
    public ResponseData countSatisfyDegree() {
        List<ChartStrData> chartStrData = diagnosisMapper.countSatisfyDegree();
        if (chartStrData == null || chartStrData.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), chartStrData);
    }

    /**
     * 统计词云
     * @return
     */
    public ResponseData countWordCloud() {
        LambdaQueryWrapper<Diagnosis> lqw = new LambdaQueryWrapper<>();
        lqw.select(Diagnosis::getDiagnosis);
        List<Map<String, Object>> wordsMap = diagnosisMapper.selectMaps(lqw);
        // 开始统计
        List<Map<String, Object>> results = new ArrayList<>();
        wordsMap.forEach(item -> {
            if (item.get("diagnosis") != null){
                List<String> keywordList = HanLP.extractKeyword(item.get("diagnosis").toString(), 2);

                for (String keyword : keywordList) {
                    boolean found = false;
                    for (Map<String, Object> keywordCountMap : results) {
                        if (keywordCountMap.get("name").equals(keyword)) {
                            keywordCountMap.put("value", (int)keywordCountMap.get("value") + 1);
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        Map<String, Object> keywordCountMap = new HashMap<>();
                        keywordCountMap.put("name", keyword);
                        keywordCountMap.put("value", 1);
                        results.add(keywordCountMap);
                    }
                }
            }
        });
        // 返回数据
        if (results.isEmpty()){
            return new ResponseData(HttpStatusEnum.DATA_NOT_EXIST.getCode(), HttpStatusEnum.DATA_NOT_EXIST.getMessage());
        }
        return new ResponseData(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), results);
    }
}
